package 遍历器;

import 抽象语法树节点.*;
import 抽象语法树节点.后缀表达式.*;
import 抽象语法树节点.字面量类.*;
import 抽象语法树节点.表达式类.*;
import 抽象语法树节点.表达式类.二元运算类.*;
import 抽象语法树节点.表达式类.关系运算类.*;
import 抽象语法树节点.表达式类.匹值运算类.*;
import 抽象语法树节点.语句类.判断语句;
import 抽象语法树节点.语句类.赋值语句;
import 抽象语法树节点.语句类.返回语句;

public class 抽象语法树基础遍历器 {

    public 抽象语法树基础遍历器(抽象语法树基础监听器 监听器) {
        this.监听器 = 监听器;
    }

    private final 抽象语法树基础监听器 监听器;


    public void 遍历(代码块 节点) {
        监听器.进入代码块(节点);

        if (节点.语句 != null) {
            for (var 语句 : 节点.语句) {
                遍历(语句);
            }
        }

        监听器.离开代码块(节点);
    }

    public void 遍历(参数列表 节点) {
        监听器.进入参数列表(节点);

        if (节点.参数 != null) {
            for (var 参数 : 节点.参数) {
                遍历(参数);
            }
        }

        监听器.离开参数列表(节点);
    }


    public void 遍历(变量定义 节点) {
        监听器.进入变量定义(节点);

        遍历(节点.类型);
        遍历(节点.初始值);

        监听器.离开变量定义(节点);
    }

    public void 遍历(抽象语法树 节点) {
        监听器.进入抽象语法树(节点);

        if (节点 instanceof 代码块 代码块) {
            遍历(代码块);
        } else if (节点 instanceof 参数列表 参数列表) {
            遍历(参数列表);
        } else if (节点 instanceof 变量定义 变量定义) {
            遍历(变量定义);
        } else if (节点 instanceof 数组定义 数组定义) {
            遍历(数组定义);
        } else if (节点 instanceof 方法定义 方法定义) {
            遍历(方法定义);
        } else if (节点 instanceof 标识符 标识符) {
            遍历(标识符);
        } else if (节点 instanceof 类型引用 类型引用) {
            遍历(类型引用);
        } else if (节点 instanceof 结构体定义 结构体定义) {
            遍历(结构体定义);
        } else if (节点 instanceof 编译单元 编译单元) {
            遍历(编译单元);
        } else if (节点 instanceof 表达式列表 表达式列表) {
            遍历(表达式列表);
        } else if (节点 instanceof 函数调用表达式 函数调用) {
            遍历(函数调用);
        } else if (节点 instanceof 成员访问表达式 成员访问) {
            遍历(成员访问);
        } else if (节点 instanceof 数组访问表达式 数组访问) {
            遍历(数组访问);
        } else if (节点 instanceof 字符型字面量 字符型字面量) {
            遍历(字符型字面量);
        } else if (节点 instanceof 整数型字面量 整数型字面量) {
            遍历(整数型字面量);
        } else if (节点 instanceof 浮点型字面量 浮点型字面量) {
            遍历(浮点型字面量);
        } else if (节点 instanceof 逻辑型字面量 逻辑型字面量) {
            遍历(逻辑型字面量);
        } else if (节点 instanceof 取反表达式 取反表达式) {
            遍历(取反表达式);
        } else if (节点 instanceof 负数表达式 负数表达式) {
            遍历(负数表达式);
        } else if (节点 instanceof 二元运算表达式 二元运算表达式) {
            遍历(二元运算表达式);
        } else if (节点 instanceof 关系运算表达式 关系运算表达式) {
            遍历(关系运算表达式);
        } else if (节点 instanceof 匹值运算表达式 匹值运算表达式) {
            遍历(匹值运算表达式);
        } else if (节点 instanceof 判断语句 判断语句) {
            遍历(判断语句);
        } else if (节点 instanceof 赋值语句 赋值语句) {
            遍历(赋值语句);
        } else if (节点 instanceof 返回语句 返回语句) {
            遍历(返回语句);
        }

        监听器.离开抽象语法树(节点);
    }

    public void 遍历(数组定义 节点) {
        监听器.进入数组定义(节点);

        遍历(节点.元素类型);
        遍历(节点.初始值);

        监听器.离开数组定义(节点);
    }

    public void 遍历(方法定义 节点) {
        监听器.进入方法定义(节点);


        遍历(节点.返回值类型);

        if (节点.参数列表 != null) {
            遍历(节点.参数列表);
        }

        遍历(节点.代码块);

        监听器.离开方法定义(节点);
    }

    public void 遍历(标识符 节点) {
        监听器.进入标识符(节点);
        监听器.离开标识符(节点);
    }

    public void 遍历(类型引用 节点) {
        监听器.进入类型引用(节点);
        监听器.离开类型引用(节点);
    }

    public void 遍历(结构体定义 节点) {
        监听器.进入结构体定义(节点);

        if (节点.成员 != null) {
            for (var 成员 : 节点.成员) {
                遍历(成员);
            }
        }

        监听器.离开结构体定义(节点);
    }

    public void 遍历(编译单元 节点) {
        监听器.进入编译单元(节点);

        if (节点.定义 != null) {
            for (var 定义 : 节点.定义) {
                遍历(定义);
            }
        }

        监听器.离开编译单元(节点);
    }

    public void 遍历(表达式列表 节点) {
        监听器.进入表达式列表(节点);

        if (节点.表达式 != null) {
            for (var 表达式 : 节点.表达式) {
                遍历(表达式);
            }
        }

        监听器.离开表达式列表(节点);
    }

    public void 遍历(函数调用表达式 节点) {
        监听器.进入函数调用表达式(节点);

        遍历(节点.函数);
        if (节点.参数 != null) {
            遍历(节点.参数);
        }

        监听器.离开函数调用表达式(节点);
    }


    public void 遍历(成员访问表达式 节点) {
        监听器.进入成员访问表达式(节点);
        遍历(节点.对象);
        监听器.离开成员访问表达式(节点);
    }

    public void 遍历(数组访问表达式 节点) {
        监听器.进入数组访问表达式(节点);
        遍历(节点.数组);
        遍历(节点.下标);
        监听器.离开数组访问表达式(节点);
    }


    // 字面量类

    public void 遍历(字符型字面量 节点) {
        监听器.进入字符型字面量(节点);
        监听器.离开字符型字面量(节点);
    }

    public void 遍历(整数型字面量 节点) {
        监听器.进入整数型字面量(节点);
        监听器.离开整数型字面量(节点);
    }

    public void 遍历(浮点型字面量 节点) {
        监听器.进入浮点型字面量(节点);
        监听器.离开浮点型字面量(节点);
    }

    public void 遍历(逻辑型字面量 节点) {
        监听器.进入逻辑型字面量(节点);
        监听器.离开逻辑型字面量(节点);
    }


    // 表达式类

    public void 遍历(二元运算表达式 节点) {
        监听器.进入二元运算表达式(节点);

        if (节点 instanceof 乘法表达式 乘法表达式) {
            遍历((乘法表达式) 节点);
        } else if (节点 instanceof 减法表达式 减法表达式) {
            遍历((减法表达式) 节点);
        } else if (节点 instanceof 加法表达式 加法表达式) {
            遍历((加法表达式) 节点);
        } else if (节点 instanceof 除法表达式 除法表达式) {
            遍历((除法表达式) 节点);
        }

        监听器.离开二元运算表达式(节点);
    }


    public void 遍历(关系运算表达式 节点) {
        监听器.进入关系运算表达式(节点);

        if (节点 instanceof 大于等于表达式 大于等于表达式) {
            遍历((大于等于表达式) 节点);
        } else if (节点 instanceof 大于表达式 大于表达式) {
            遍历((大于表达式) 节点);
        } else if (节点 instanceof 小于等于表达式 小于等于表达式) {
            遍历((小于等于表达式) 节点);
        } else if (节点 instanceof 小于表达式 小于表达式) {
            遍历((小于表达式) 节点);
        }

        监听器.离开关系运算表达式(节点);
    }

    public void 遍历(匹值运算表达式 节点) {
        监听器.进入匹值运算表达式(节点);

        if (节点 instanceof 不等于表达式 不等于表达式) {
            遍历((不等于表达式) 节点);
        } else if (节点 instanceof 相等表达式 相等表达式) {
            遍历((相等表达式) 节点);
        }

        监听器.离开匹值运算表达式(节点);
    }

    public void 遍历(取反表达式 节点) {
        监听器.进入取反表达式(节点);
        遍历(节点.值);
        监听器.离开取反表达式(节点);
    }


    public void 遍历(负数表达式 节点) {
        监听器.进入负数表达式(节点);
        遍历(节点.值);
        监听器.离开负数表达式(节点);
    }


    // 表达式类-二元运算类

    public void 遍历(乘法表达式 节点) {
        监听器.进入乘法表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开乘法表达式(节点);
    }


    public void 遍历(减法表达式 节点) {
        监听器.进入减法表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开减法表达式(节点);
    }

    public void 遍历(加法表达式 节点) {
        监听器.进入加法表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开加法表达式(节点);
    }

    public void 遍历(除法表达式 节点) {
        监听器.进入除法表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开除法表达式(节点);
    }


    // 表达式类-关系运算类

    public void 遍历(大于等于表达式 节点) {
        监听器.进入大于等于表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开大于等于表达式(节点);
    }

    public void 遍历(大于表达式 节点) {
        监听器.进入大于表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开大于表达式(节点);
    }

    public void 遍历(小于等于表达式 节点) {
        监听器.进入小于等于表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开小于等于表达式(节点);
    }

    public void 遍历(小于表达式 节点) {
        监听器.进入小于表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开小于表达式(节点);
    }


    // 表达式类-匹值运算类

    public void 遍历(不等于表达式 节点) {
        监听器.进入不等于表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开不等于表达式(节点);
    }

    public void 遍历(相等表达式 节点) {
        监听器.进入相等表达式(节点);
        遍历(节点.左值);
        遍历(节点.右值);
        监听器.离开相等表达式(节点);
    }


    // 语句类

    public void 遍历(判断语句 节点) {
        监听器.进入判断语句(节点);

        遍历(节点.条件);
        遍历(节点.真值语句);

        if (节点.假值语句 != null) {
            遍历(节点.假值语句);
        }

        监听器.离开判断语句(节点);
    }

    public void 遍历(赋值语句 节点) {
        监听器.进入赋值语句(节点);

        遍历(节点.左值);
        遍历(节点.右值);

        监听器.离开赋值语句(节点);
    }

    public void 遍历(返回语句 节点) {
        监听器.进入返回语句(节点);
        遍历(节点.返回值);
        监听器.离开返回语句(节点);
    }
}
